Reward Contract Spec (1)

PaymentSplitter Contract

The PaymentSplitter contract allows an arbitrary number of payees to receive a proportional share of FIL payments sent to the contract. The contract employs a pull payment model, meaning that the payees must actively withdraw their shares. The contract emits events to log payee additions, received payments, and released payments.

Requirements

  1. Asynchrony: Nodes should be able to claim all prior rewards at any point in the future
  1. The sponsor must be able to add funds for the payout in each epoch. They must be able to add payouts for multiple epochs in one transaction.
  1. The payout amount must be clear to the participants before they join and they should not need to trust the sponsor to pay up.

Data model

Share

A share is a fixed fraction of the total balance available to be distributed among peers. Each share is associated with a payee and will be marked as released once it has been claimed.

Payee

The address of a peer that can claim a share.

Variables

_totalShares (private, uint256)

Represents the total number of shares allocated to all payees. A payee's proportion of total payments is determined by the ratio of their shares to _totalShares.

_totalReleased (private, uint256)

Represents the total amount of FIL that has been released to payees so far.

_shares (private, mapping)

Maps each payee's address to their allocated shares.

_released (private, mapping)

Maps each payee's address to the amount of FIL they have withdrawn so far.

_payees (private, address[])

A list of the addresses of all payees.

Functions

initialize(address[] memory payees_, uint256[] memory shares_) external payable initializer

This function is called once, at contract deployment. It sets the initial list of payees and their corresponding share amounts. The function requires that payees_ and shares_ have the same length, that the length is greater than zero, and that no address in payees_ is zero or the contract's own address.

receive() external payable virtual

This fallback function is called whenever the contract receives FIL. It emits a PaymentReceived event with the sender's address and the amount of FIL received.

release(address account) public virtual

A payee uses this function to withdraw their available FIL. The function requires that the payee has been allocated at least one share, and that they are due to receive at least one unit of FIL. It updates the _totalReleased and _released variables and emits a PaymentReleased event.

_pendingPayment(address account, uint256 totalReceived, uint256 alreadyReleased) private view returns (uint256)

This private helper function calculates the amount of FIL that a payee can withdraw, based on the total amount of FIL received by the contract, the total amount already released to the payee, and the payee's share allocation.

_addPayee(address account, uint256 shares_) private

This private helper function adds a new payee and their associated share allocation to the contract. The function requires that the address is not zero, the share amount is not zero, and the payee has not been added before. It updates the _payees, _shares, and _totalShares variables and emits a PayeeAdded event.

Getters

totalShares()

Returns the total shares

totalReleased()

Returns the total released FIL

payees()

Returns the list of payees

shares(address account)

Returns the number of shares for a specific account

released(address account)

Returns the amount of FIL released for a specific account

releasable(address account)

Returns the amount of FIL releasable for a specific account

Events

PayeeAdded(address account, uint256 shares)

This event is emitted when a new payee is added.

PaymentReleased(address to, uint256 amount)

This event is emitted when a payee withdraws FIL from the contract.

PaymentReceived(address from, uint256)

TODO

References